package com.dcivision.dms.core;

import java.sql.Connection;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.LogFactoryImpl;

import com.dcivision.dms.DmsErrorConstant;
import com.dcivision.dms.DmsOperationConstant;
import com.dcivision.dms.bean.DmsDocument;
import com.dcivision.dms.bean.DmsValidation;
import com.dcivision.dms.bean.DmsVersion;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.DWRFacade;
import com.dcivision.framework.DataSourceFactory;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.MessageResourcesFactory;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;

public class DmsDocumentCheckoutFacade extends DWRFacade {
  
  protected Log log = new LogFactoryImpl().getInstance(this.getClass());
  Connection conn = null;

  public DmsDocumentCheckoutFacade() {
    super();
    
  }
  
  public String checkoutRecord(String documentID, String curFunctionCode){
    SessionContainer sessionContainer = this.getSessionContainer();
    conn = this.getDBConnection();
    java.util.Date triggerTime = null;
    org.quartz.SimpleTrigger trigger = null;
    int val = 0;
    java.sql.Timestamp src= null;
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
    
    String message = null;
    
    try {
      DmsDocument dmsDocument =docRetrievalManager.getDocument(TextUtility.parseIntegerObj(documentID));

      //Add By Jim Zhou       2007/0110       EIP-1292
      DocumentValidateManager docValidateManager = new DocumentValidateManager(sessionContainer, conn);
      StringBuffer messageTmp = new StringBuffer();

      DmsValidation validation = docValidateManager.validateOperateAction(dmsDocument, false ,"T");
      List lstIdMisRight = validation.getLstIdReject();
      List lstIdBeLocked = validation.getLstIdlocked();
      List lstIdBeDeleted = validation.getLstIdDeleted();
      List lstIdBeArchived = validation.getLstIdArchived();
      List lstIdRelationship = validation.getLstIdHaveRelationship();
      if (!lstIdMisRight.isEmpty() ||
          !lstIdBeLocked.isEmpty() ||
          !lstIdBeDeleted.isEmpty()){
        for (int i=0; i<lstIdMisRight.size(); i++) {
          messageTmp.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"errors.dms.no_permission",docRetrievalManager.getLocationPath((Integer)lstIdMisRight.get(i))) + "\n");
        }
        for (int i=0; i<lstIdBeLocked.size(); i++) {
          messageTmp.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"errors.dms.been_checkout",docRetrievalManager.getLocationPath((Integer)lstIdBeLocked.get(i))) + "\n");
        }
        for (int i=0; i<lstIdBeDeleted.size(); i++) {
          messageTmp.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"errors.dms.been_deleted",docRetrievalManager.getLocationPath((Integer)lstIdBeDeleted.get(i))) + "\n");
        }
        for (int i=0; i<lstIdBeArchived.size(); i++) {
          messageTmp.append(MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"errors.dms.been_archived",docRetrievalManager.getLocationPath((Integer)lstIdBeArchived.get(i))) + "\n");
        }
        message = messageTmp.toString();
        //Add End
      } else if(GlobalConstant.STATUS_LOCKED.equals( dmsDocument.getItemStatus())){      //checkout document must check doucment item status is active
        // duplicate checkout 
        //message = DmsErrorConstant.DUPLICATE_FILE_CHECKOUT;
        message = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),DmsErrorConstant.DUPLICATE_FILE_CHECKOUT);
      } else {
        //if DMS_CHECKOUT_EXPIRE_DAY>0 then perform then check in Scheduler
        if(TextUtility.parseInteger(SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_CHECKOUT_EXPIRE_DAY)) > 0){
          
          val = TextUtility.parseInteger(SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_CHECKOUT_EXPIRE_DAY));
          src= Utility.getCurrentTimestamp();
          triggerTime =Utility.addDay(src,val);
          //triggerTime =Utility.addMinute(src,val);  
          
          org.quartz.Scheduler sched = com.dcivision.framework.SchedulerFactory.getScheduler(); 
          
          org.quartz.JobDataMap dataMap = new org.quartz.JobDataMap();
          dataMap.put("documentID", documentID);
          dataMap.put("userID", TextUtility.formatIntegerObj(sessionContainer.getUserRecordID()));
          
          org.quartz.JobDetail job = new org.quartz.JobDetail(
              "checkout expiry time " + new java.util.Date(),
              "CHECKOUT_JOBGROUP"+Math.random(),
              com.dcivision.dms.core.DmsCheckoutExpiryTime.class);
          job.setJobDataMap(dataMap);
          
          log.info("******** Schedule date: " + triggerTime.toString());
          trigger = new org.quartz.SimpleTrigger("CheckInExpirt_"+documentID,"CHECKIN_GROUP"+Math.random(),triggerTime, null,0,0);
          
          trigger.setMisfireInstruction(org.quartz.SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW);
          log.info("******** Trigger created");
          log.info(job.getFullName() + " will run at: " + trigger.getNextFireTime() + " & repeat: " + trigger.getRepeatCount() + "/" + trigger.getRepeatInterval());
          
          java.util.Date ft = sched.scheduleJob(job, trigger);
          sched = null;
          //this.scheduledJobVec.clear();
        }
        
        //checkout start
        dmsDocument.setCurFunctionCode(curFunctionCode);
        if (DmsOperationConstant.LIST_PERSONAL_HOME.equals(curFunctionCode)) {
          dmsDocument.setCurFunctionCode(docRetrievalManager.getCurFunctionCode(dmsDocument));
        }
        VersionControlManager versionControlManager = new VersionControlManager(sessionContainer, conn);
        versionControlManager.checkoutDocument(DmsVersion.EXCLUSIVE_LOCK, dmsDocument);
        conn.commit();
        versionControlManager.release();
        //checkout end
        try{
          sessionContainer=null;
        } catch (Exception e) { 
          log.error(e, e);
        }
        message = GlobalConstant.TRUE;
      }
    } catch (ApplicationException e) {
      log.error(e, e);
      message = GlobalConstant.FALSE;
    } catch (Exception e) {
      log.error("Error in Scheduler.", e);
      //message = ErrorConstant.SYS_SCHEDULER_ERROR;
      message = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),ErrorConstant.SYS_SCHEDULER_ERROR);
    } finally {
      this.closeConnection();
    }
    return message;
  }
  
  private Connection getDBConnection(){
    if(this.conn!=null){
      return conn;
    }else{
      try{
        conn=DataSourceFactory.getConnection();
      }catch(Exception e){
        log.error("get Connection error!");
      }
      return conn;
    }
  }
  
  private void closeConnection() {
    if(this.conn != null ){
      try { conn.close(); } catch (Exception ignore) {} finally { conn = null; }
      log.info("Close Connection Succeed");
    }
  }

}
